fix: xembed tray popup window position correction for stashed container#1608
Conversation
|
Skipping CI for Draft Pull Request. |
7f02618 to
22b3fc9
Compare
之前托盘位置总是相对于任务栏的 wl_surface 的,会导致向上收起区域的偏移 位置不正确。此提交增加了托盘位于哪个区域的区分,并根据对应的位置决定 所基于的 wl_surface 是哪个。 PMS: BUG-360349 Log:
22b3fc9 to
1083e55
Compare
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: BLumia The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
1 similar comment
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: BLumia The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
deepin pr auto review这份代码变更主要实现了将 XEmbed 窗口移动的参考坐标系从固定的 Dock 面板窗口改为动态的“锚点窗口”,并引入了基于 整体设计思路清晰,但在线程安全、内存管理、类型转换和代码健壮性方面存在一些需要重点关注的问题。以下是详细的审查意见: 1. 严重问题:线程安全与对象生命周期文件: struct CallbackData { uint32_t wid; WaylandDockHelper *helper; };
static struct wl_callback_listener s_callbackListener = {
.done = [](void *data, wl_callback *callback, uint32_t callback_data) {
auto *d = static_cast<CallbackData *>(data);
bool success = (callback_data == 0);
Q_EMIT d->helper->xembedWindowMoveResult(d->wid, success);
wl_callback_destroy(callback);
delete d;
}
};
wl_callback_add_listener(cb, &s_callbackListener, new CallbackData{wid, this});
修改后代码示例: struct CallbackData {
uint32_t wid;
QPointer<WaylandDockHelper> helper; // 使用 QPointer 防止悬空指针
};
static struct wl_callback_listener s_callbackListener = {
.done = [](void *data, wl_callback *callback, uint32_t callback_data) {
auto *d = static_cast<CallbackData *>(data);
bool success = (callback_data == 0);
// 安全地将信号发射转移到 Qt 主线程
if (d->helper) {
QMetaObject::invokeMethod(d->helper, [helper = d->helper, wid = d->wid, success]() {
Q_EMIT helper->xembedWindowMoveResult(wid, success);
}, Qt::QueuedConnection);
}
wl_callback_destroy(callback);
delete d;
}
};
wl_callback_add_listener(cb, &s_callbackListener, new CallbackData{wid, QPointer<WaylandDockHelper>(this)});2. 严重问题:错误的类型转换文件: auto waylandWindow = dynamic_cast<QtWaylandClient::QWaylandWindow*>(anchorWindow->handle());
修改思路示例: // 假设 anchorWindow 对应的 backend 是 QWaylandQuickSurface
#include <QtWaylandCompositor/QWaylandQuickSurface>
// ...
if (anchorWindow) {
// 正确的合成器侧转换方式,具体取决于你的 Qt 版本和窗口创建方式
auto waylandSurface = dynamic_cast<QtWaylandCompositor::QWaylandQuickSurface*>(anchorWindow->handle());
if (waylandSurface && waylandSurface->waylandSurface()) {
anchorSurface = waylandSurface->waylandSurface()->object();
} else {
qWarning() << "Failed to cast anchorWindow to QWaylandQuickSurface";
}
}3. 代码质量:QML 中的匿名函数连接与内存泄漏风险文件: Panel.xembedWindowMoveResult.connect(function(wid, success) {
DockCompositor.notifyXEmbedWindowMoveResult(wid, success)
})
修改后代码示例: // 在 Window 或 Item 中定义函数
function handleXEmbedWindowMoveResult(wid, success) {
DockCompositor.notifyXEmbedWindowMoveResult(wid, success)
}
// 连接时传入函数引用
Panel.xembedWindowMoveResult.connect(handleXEmbedWindowMoveResult)
// 在 Component.onDestruction 中断开
Component.onDestruction: {
Panel.xembedWindowMoveResult.disconnect(handleXEmbedWindowMoveResult)
}4. 代码健壮性:PluginSurface 中 AnchorWindow 的更新与同步文件: pluginItem.plugin.setAnchorWindow(pluginItem.Window.window)
pluginItem.plugin.updatePluginGeometry(...)void PluginSurface::setAnchorWindow(QQuickWindow *window) {
m_anchorWindow = window;
}
void PluginSurface::setAnchorWindow(QQuickWindow *window)
{
if (m_anchorWindow == window)
return;
if (!window) {
qWarning() << "PluginSurface::setAnchorWindow: setting null anchor window for" << m_pluginId;
}
m_anchorWindow = window;
}5. 代码性能:QML 中不必要的日志输出文件: onMoveXEmbedWindowRequested: (wid, pluginId, itemKey, dx, dy, anchorWindow) => {
console.log("move xembed window requested:", wid, pluginId, itemKey, dx, dy, "anchorWindow:", anchorWindow)
6. 代码安全与逻辑:异步回调与并发请求文件: // pluginmanagerextension.cpp
m_pendingXEmbedCallbacks[xembed_winid] = {callback, resource->handle};
总结最关键且必须修复的是 第2点(类型转换错误),这会导致整个 |
之前托盘位置总是相对于任务栏的 wl_surface 的,会导致向上收起区域的偏移
位置不正确。此提交增加了托盘位于哪个区域的区分,并根据对应的位置决定
所基于的 wl_surface 是哪个。
PMS: BUG-360349